﻿// *----------------------------------------------------------------
// Copyright (C) 2017 通通优品
// 版权所有。
// 
// 类名：UnitHelper.cs
// 功能描述：TongTongMall.MallWeb.Core
// 
// Create User：jym 2017/02/09
// 
// Edit User：UserName,EditTime
// Describe：Describe
// ----------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using TEC.Public.Common;
using TEC.Public.Component.AliAopSdk.Util;
using TEC.Public.Component.OpenPlat.Tencent.WeiXin;
//using TEC.Web.Component.KuaiDi;
//using TongTongMall.MallWeb.Core.Order.Enum;
//using TongTongMall.MallWeb.Core.ShoppingCart.Models;

namespace TongTongMall.MallWeb.Core.Instance
{
    public static class UnityHelper
    {
        /// <summary>
        /// 获取列表指定索引指定获取返回值方法  如：List.GetListValue(0, item => item.ImageURI, string.Empty)
        /// </summary>
        /// <typeparam name="T">列表对象类型</typeparam>
        /// <typeparam name="R">返回值类型</typeparam>
        /// <param name="arr">列表</param>
        /// <param name="index">索引</param>
        /// <param name="getFunc">获取返回值方法</param>
        /// <param name="def">默认值</param>
        /// <returns></returns>
        public static R GetListValue<T, R>(this IList<T> arr, int index, Func<T, R> getFunc, R def = default(R))
        {
            if (arr != null && arr.Count > index)
            {
                return getFunc(arr[index]);
            }
            return def;
        }
        /// <summary>
        /// 获取键值对指定key的值
        /// </summary>
        /// <typeparam name="K">Key类型</typeparam>
        /// <typeparam name="V">值类型</typeparam>
        /// <typeparam name="R">返回类型</typeparam>
        /// <param name="dic">集合</param>
        /// <param name="key">key值</param>
        /// <param name="getFunc">获取返回值方法</param>
        /// <param name="def">默认值</param>
        /// <returns></returns>
        public static R GetDictionaryValue<K, V, R>(this IDictionary<K, V> dic, K key, Func<V, R> getFunc, R def = default(R))
        {
            if (dic != null && dic.ContainsKey(key))
            {
                return getFunc(dic[key]);
            }
            return def;
        }

        /// <summary>
        ///  获取键值对指定key的值
        /// </summary>
        /// <typeparam name="K">Key类型</typeparam>
        /// <typeparam name="V">值类型</typeparam>
        /// <typeparam name="R">返回类型</typeparam>
        /// <param name="dic">集合</param>
        /// <param name="key">key值</param>
        /// <param name="def">默认值</param>
        /// <returns></returns>
        public static V GetDictionaryValue<K, V>(this IDictionary<K, V> dic, K key, V def = default(V))
        {
            if (dic != null && dic.ContainsKey(key))
            {
                return dic[key];
            }
            return def;
        }

        /// <summary>
        /// 页码参数处理
        /// </summary>
        /// <param name="pagesize"></param>
        /// <param name="curpage"></param>

        public static void ParamPageSize(ref int pagesize, ref int curpage)
        {
            if (curpage < 1)
            {
                curpage = 1;
            }
            if (pagesize < 1 || pagesize > 100)
            {
                pagesize = 10;
            }
        }

        /// <summary>
        /// 统一日期时间输出格式
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateFormat(this DateTime value)
        {
            return value.ToString("yyyyMMddHHmmss");
        }
        /// <summary>
        /// 统一日期时间输出格式（支持可空类型）
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateFormat(this DateTime? value, string def)
        {
            if (value.HasValue)
                return value.Value.ToString("yyyyMMddHHmmss");
            return def;
        }

        /// <summary>
        /// 预售发货日期格式化(X月X日)
        /// </summary>
        /// <param name="value"></param>
        /// <param name="def"></param>
        /// <returns></returns>
        public static string DateFormatForPreSellSend(this DateTime? value, string def)
        {
            if (value.HasValue)
                return string.Format("{0:M月dd日}", value);
            return def;
        }

        /// <summary>
        /// 预售结束日期格式化(X月X日 HHMMss)
        /// </summary>
        /// <param name="value"></param>
        /// <param name="def"></param>
        /// <returns></returns>
        public static string DateFormatForPreSellEnd(this DateTime? value, string def)
        {
            if (value.HasValue)
                return string.Format("{0:M月dd日 HH:mm:ss}", value);
            return def;
        }


        public static string MoneyFormat(this decimal value)
        {

            return value.ToString("#.##");

        }

        public static string MoneyFormat(this decimal? value)
        {
            if (value.HasValue)
            {
                return value.Value.MoneyFormat();
            }
            return string.Empty;
        }

        public static string DecimalFormat(this decimal? value)
        {
            if (value.HasValue)
            {
                return value.Value.ToString("0.00");
            }
            return string.Empty;
        }


        public static string DecimalFormat(this decimal value)
        {
            return value.ToString("0.00");
        }

        /// <summary>
        /// 四舍五入取整
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DecimaRoundlFormat(this decimal value)
        {
            return value.ToString("0");
        }

        /// <summary>
        /// 获取当前域名根地址 如：http://www.tontongmall.com:806/default.aspx?id=1  获取值为   http://www.tontongmall.com:806
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetDomainUrl(this string url)
        {
            try
            {
                var uri = new Uri(url);
                return GetDomainUrl(uri);
            }
            catch
            {
                return url;
            }

        }

        /// <summary>
        /// 获取当前域名根地址 如：http://www.tontongmall.com:806/default.aspx?id=1  获取值为   http://www.tontongmall.com:806
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetDomainUrl(this Uri uri)
        {
            return $"{uri.Scheme}://{uri.Authority}";
        }

        /// <summary>
        /// Url查询字符串加参数
        /// </summary>
        /// <param name="url"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string AddQueryStringParam(this string url, string name, string value)
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                return $"{name}={value}";
            }
            else
            {
                if (url.IndexOf('?') > -1)
                {
                    return $"{url}&{name}={value}";
                }
                else
                {
                    return $"{url}?{name}={value}";
                }
            }
        }
        public static string AddQueryStringParam(this string url, NameValueCollection collection)
        {
            foreach (string key in collection.Keys)
            {
                url = url.AddQueryStringParam(key, collection[key]);
            }
            return url;
        }
        public static string AddQueryStringParam(this string url, IDictionary<string, string> collection)
        {
            foreach (string key in collection.Keys)
            {
                url = url.AddQueryStringParam(key, collection[key]);
            }
            return url;
        }
        /// <summary>
        /// 获取Header
        /// </summary>
        /// <param name="request"></param>
        /// <param name="name"></param>
        /// <param name="def"></param>
        /// <returns></returns>
        public static string GetHeaderValue(this HttpRequestMessage request, string name, string def = null)
        {

            IEnumerable<string> values;
            if (request.Headers.TryGetValues(name, out values))
            {
                return values.SingleOrDefault();
            }
            return def;
        }



        #region WXCache
        const string ACCESSTOKEN_CACHE_KEY = "____WeiXinACCESSTOKEN_CACHE_KEY";
        public static string ACCESSTOKEN_FILE_SAVE_PATH = "~/App_Data/WeiXinAccessToken";
        public static AccessToken GetAccessTokenFromCache()
        {
            var cache = HttpContext.Current.Application[ACCESSTOKEN_CACHE_KEY] as AccessToken;
            if (cache == null || string.IsNullOrWhiteSpace(cache.access_token))
            {
                try
                {
                    string json = System.IO.File.ReadAllText(HttpHelper.GetPhyPath(ACCESSTOKEN_FILE_SAVE_PATH));
                    cache = json.JsonDeserialize<AccessToken>(null, false);
                }
                catch (Exception ex)
                {

                    DefaultInstance.Instance.AliPayLoggerHelper.Error("从文件读取WeiXinAccessToken出错", ex);
                }

            }
            return cache;
        }

        public static void SetAccessTokenToCache(AccessToken access_Token)
        {
            var cache = HttpContext.Current.Application[ACCESSTOKEN_CACHE_KEY] as AccessToken;
            try
            {
                string path = HttpHelper.GetPhyPath(ACCESSTOKEN_FILE_SAVE_PATH);
                System.IO.File.WriteAllText(path, access_Token.JsonSerialize());
            }
            catch (Exception ex)
            {

                DefaultInstance.Instance.AliPayLoggerHelper.Error("写WeiXinAccessToken入文件出错", ex);
            }
        }

        const string JSAPITICKET_CACHE_KEY = "____WeiXinJSAPITICKET_CACHE_KEY";
        public static string JSAPITICKET_FILE_SAVE_PATH = "~/App_Data/WeiXinJsApiTicket";
        public static JsApiTicket GetJsApiTicketFromCache()
        {
            var cache = HttpContext.Current.Application[JSAPITICKET_CACHE_KEY] as JsApiTicket;
            if (cache == null || string.IsNullOrWhiteSpace(cache.ticket))
            {
                try
                {
                    string json = System.IO.File.ReadAllText(HttpHelper.GetPhyPath(JSAPITICKET_FILE_SAVE_PATH));
                    cache = json.JsonDeserialize<JsApiTicket>(null, false);
                }
                catch (Exception ex)
                {

                    DefaultInstance.Instance.AliPayLoggerHelper.Error("从文件读取WeiXinJsApiTicket出错", ex);
                }

            }
            return cache;
        }

        public static void SetJsApiTicketToCache(JsApiTicket ticket)
        {
            HttpContext.Current.Application[JSAPITICKET_CACHE_KEY] = ticket;
            try
            {
                string path = HttpHelper.GetPhyPath(JSAPITICKET_FILE_SAVE_PATH);
                System.IO.File.WriteAllText(path, ticket.JsonSerialize());
            }
            catch (Exception ex)
            {

                DefaultInstance.Instance.AliPayLoggerHelper.Error("写WeiXinJsApiTicket入文件出错", ex);
            }
        }

        public class OpenIDCacheException : Exception
        {
            public OpenIDCacheException(string message) : base(message) { }
        }


        #endregion


        /// <summary>
        /// 移除Html标记
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string RemoveHtmlSp(string content)
        {
            string regexstr = @"<[^>]*>";
            return Regex.Replace(content, regexstr, string.Empty, RegexOptions.IgnoreCase).Replace("&amp;nbsp;", string.Empty).Replace("&nbsp;", string.Empty).Replace("&amp;quot;", string.Empty).Replace("&lt;", string.Empty).Replace("&gt;", string.Empty);

        }

        /// <summary>
        /// 手机号加密格式 150****5661
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public static string MobileNumSecretFormat(this string mobile)
        {
            if (string.IsNullOrWhiteSpace(mobile)) return string.Empty;
            return Regex.Replace(mobile, @"(?im)(\d{3})(\d{4})(\d{4})", "$1***$3");
        }

        /// <summary>
        /// 手机号加密格式 150****5661
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public static string MobileNumSecretFormat(this string mobile, bool doit = false)
        {
            if (!doit)
                return mobile ?? string.Empty;
            if (string.IsNullOrWhiteSpace(mobile)) return string.Empty;
            return Regex.Replace(mobile, @"(?im)(\d{3})(\d{4})(\d{4})", "$1****$3");
        }

        /// <summary>
        /// 昵称加密格式 加***式
        /// </summary>
        /// <param name="nickname"></param>
        /// <returns></returns>
        public static string NickNameSecretFormat(this string nickname)
        {
            if (string.IsNullOrWhiteSpace(nickname)) return string.Empty;
            return Regex.Replace(nickname, @"^(.{1})(.*)(.{1})$", "$1***$3");
        }

        /// <summary>
        /// 快递公司 1：申通；2：中通；3：圆通；4：
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public static string WaybillCompany(this byte value)
        {
            switch (value)
            {
                case 1:
                    return "申通快递";
                case 2:
                    return "中通快递";
                case 3:
                    return "圆通快递";
            }
            return value.ToString();
        }

        /// <summary>
        /// 获取查询字符串的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="request"></param>
        /// <param name="name"></param>
        /// <param name="def"></param>
        /// <returns></returns>
        public static T GetQueryValue<T>(this HttpRequestMessage request, string name, T def = default(T))
        {
            var queryStrings = request.GetQueryNameValuePairs();
            if (queryStrings == null)
                return def;

            var match = queryStrings.FirstOrDefault(kv => string.Compare(kv.Key, name, true) == 0);
            if (string.IsNullOrEmpty(match.Value))
                return def;

            return match.Value.ConvertTo<T>(def);
        }

        /// <summary>
        /// 获取Header值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="request"></param>
        /// <param name="name"></param>
        /// <param name="def"></param>
        /// <returns></returns>
        public static T GetHeaderValue<T>(this HttpRequestMessage request, string name, T def = default(T))
        {
            IEnumerable<string> values;
            if (request.Headers.TryGetValues(name, out values))
            {
                return values.FirstOrDefault().ConvertTo<T>(def);
            }
            return def;
        }

        #region 获取客户端IP地址
        private const string __MS_HTTPCONTEXT = "MS_HttpContext";
        private const string __SYSTEM_SERVICEMODEL_CHANNELS_REMOTEENDPOINTMESSAGEPROPERTY =
            "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
        private const string __MS_OWINCONTEXT = "MS_OwinContext";
        /// <summary>
        /// 获取客户端IP地址
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static string GetClientIpAddress(this HttpRequestMessage request)
        {
            // Web-hosting. Needs reference to System.Web.dll
            if (request.Properties.ContainsKey(__MS_HTTPCONTEXT))
            {
                dynamic ctx = request.Properties[__MS_HTTPCONTEXT];
                if (ctx != null)
                {
                    return ctx.Request.UserHostAddress;
                }
            }

            // Self-hosting. Needs reference to System.ServiceModel.dll. 
            if (request.Properties.ContainsKey(__SYSTEM_SERVICEMODEL_CHANNELS_REMOTEENDPOINTMESSAGEPROPERTY))
            {
                dynamic remoteEndpoint = request.Properties[__SYSTEM_SERVICEMODEL_CHANNELS_REMOTEENDPOINTMESSAGEPROPERTY];
                if (remoteEndpoint != null)
                {
                    return remoteEndpoint.Address;
                }
            }

            // Self-hosting using Owin. Needs reference to Microsoft.Owin.dll. 
            if (request.Properties.ContainsKey(__MS_OWINCONTEXT))
            {
                dynamic owinContext = request.Properties[__MS_OWINCONTEXT];
                if (owinContext != null)
                {
                    return owinContext.Request.RemoteIpAddress;
                }
            }

            return null;
        }
        #endregion

        /// <summary>
        /// 价格统一处理（如小数部分）
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal PriceUnifiedHandling(this decimal value)
        {
            return decimal.Round(value, 2, MidpointRounding.ToEven);
        }

        /// <summary>
        /// 向上保留两位小数
        /// 统一处理
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal CellingHandling(this decimal value)
        {
            var floorValue = (decimal)((int)(value * 1000)) / 1000;
            return Math.Floor(floorValue * 100 + 0.9M) / 100;
        }

        /// <summary>
        /// 向下保留两位小数
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal FloorHandling(this decimal value)
        {
            int floorValue = (int)(value * 100);
            return (decimal)(floorValue * 1.0) / 100;
        }

        /// <summary>
        /// 价格统一处理（如小数部分）
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal PriceUnifiedHandling(this double value)
        {
            return ((decimal)value).PriceUnifiedHandling();
        }


        public static string ChinaRound(this decimal value)
        {
            return Math.Round(value).ToString();

        }

        /// <summary>
        /// 通过父对象实例化子对象且所有属性值的拷贝
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TChild"></typeparam>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static TChild AutoCopy<TParent, TChild>(this TParent parent) where TChild : TParent, new()
        {
            //return AutoMapper.Mapper.Map<TChild>(parent);
            TChild child = new TChild();
            var parentType = typeof(TParent);
            var properties = parentType.GetProperties();
            foreach (var propertie in properties)
            {
                //循环遍历属性
                if (propertie.CanRead && propertie.CanWrite)
                {
                    //进行属性拷贝
                    propertie.SetValue(child, propertie.GetValue(parent, null), null);
                }
            }
            return child;
        }

        #region RSA签名验证
        /// <summary>
        /// RSA验证签名
        /// </summary>
        /// <param name="content">需要验证的内容</param>
        /// <param name="signedString">签名结果</param>
        /// <param name="publicKey">公钥</param>
        /// <param name="input_charset">编码格式</param>
        /// <returns></returns>
        public static bool RSAVerify(string content, string signedString, string publicKey, string input_charset)
        {
            bool result = false;
            try
            {
                Encoding code = Encoding.GetEncoding(input_charset);
                byte[] Data = code.GetBytes(content);
                byte[] data = Convert.FromBase64String(signedString);
                RSAParameters paraPub = ConvertFromPublicKey(publicKey);

                RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
                rsaPub.ImportParameters(paraPub);
                //rsaPub.PersistKeyInCsp = false;
                //Component.AopSdk.Util.RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsaPub, publicKey);

                SHA1 sh = new SHA1CryptoServiceProvider();
                result = rsaPub.VerifyData(Data, sh, data);

            }
            catch (Exception ex)
            {
                Dictionary<string, object> param = new Dictionary<string, object>();
                param.Add("content", content);
                param.Add("signedString", signedString);
                param.Add("publicKey", publicKey);
                param.Add("input_charset", input_charset);
                Logging.LogHelper.Logger.Warn("RSA验证签名出错" + param.JoinSeparatorToString(), ex);
            }

            return result;
        }
        public static bool RSASHA256Verify(string content, string signedString, string publicKey, string input_charset)
        {
            bool result = false;
            try
            {
                Encoding code = Encoding.GetEncoding(input_charset);
                byte[] Data = code.GetBytes(content);
                byte[] data = Convert.FromBase64String(signedString);
                //RSAParameters paraPub = ConvertFromPublicKey(publicKey);
                RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
                rsaPub.PersistKeyInCsp = false;

                //rsaPub.ImportParameters(paraPub);
                RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsaPub, publicKey);

                //SHA1 sh = new SHA1CryptoServiceProvider();
                //result = rsaPub.VerifyData(Data, sh, data);
                result = rsaPub.VerifyData(Data, "SHA256", data);
            }
            catch (Exception ex)
            {
                Dictionary<string, object> param = new Dictionary<string, object>();
                param.Add("content", content);
                param.Add("signedString", signedString);
                param.Add("publicKey", publicKey);
                param.Add("input_charset", input_charset);
                Logging.LogHelper.Logger.Warn("RSA验证签名出错" + param.JoinSeparatorToString(), ex);
                //Instance.LoggerHelper.Warn("RSA验证签名出错", ex, null, "RSAVerify");
            }

            return result;
        }
        private static RSAParameters ConvertFromPublicKey(string pemFileConent)
        {

            byte[] keyData = Convert.FromBase64String(pemFileConent);
            if (keyData.Length < 162)
            {
                throw new ArgumentException("pem file content is incorrect.");
            }
            byte[] pemModulus = new byte[128];
            byte[] pemPublicExponent = new byte[3];
            Array.Copy(keyData, 29, pemModulus, 0, 128);
            Array.Copy(keyData, 159, pemPublicExponent, 0, 3);
            RSAParameters para = new RSAParameters();
            para.Modulus = pemModulus;
            para.Exponent = pemPublicExponent;
            return para;
        }
        #endregion

        /// <summary>
        /// 获取物理路径
        /// </summary>
        /// <param name="virpath"></param>
        /// <returns></returns>
        public static string PhyPath(this string virpath)
        {
            if (!string.IsNullOrWhiteSpace(virpath))
            {
                if (virpath.IndexOf("/") > -1)
                {
                    return System.AppDomain.CurrentDomain.BaseDirectory + virpath.TrimStart('/').Replace('/', '\\');
                }
            }
            return virpath;
        }

        public static byte[] PosterComplete(byte[] backdata, byte[] qrdata, int w, int h, int x, int y, string qrcode, float emSize, string fontfamilyname, float margintop, Color color)
        {

            MemoryStream backStream = null;
            MemoryStream qrStream = null;
            Image backimage = null;
            Image qrimage = null;
            Bitmap backbitmap = null;

            Graphics g = null;
            MemoryStream completeStream = null;


            byte[] img = null;
            try
            {
                backStream = new MemoryStream(backdata);
                qrStream = new MemoryStream(qrdata);
                backimage = Image.FromStream(backStream);
                qrimage = Image.FromStream(qrStream);

                backbitmap = new Bitmap(backimage.Width, backimage.Height);
                //Bitmap qrbitmap = new Bitmap(w, h);
                g = Graphics.FromImage(backbitmap);
                g.Clear(Color.White);
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(backimage, 0, 0, backbitmap.Width, backbitmap.Height);

                g.DrawImage(qrimage, x, y, w, h);

                #region 写上字
                StringFormat drawFormat = new StringFormat();
                drawFormat.Alignment = StringAlignment.Center;
                g.DrawString(qrcode, new Font(new FontFamily(fontfamilyname), emSize), new SolidBrush(color), new RectangleF(0, y + h + margintop, backimage.Width, h), drawFormat);
                #endregion

                completeStream = new MemoryStream();
                backbitmap.Save(completeStream, ImageFormat.Png);
                img = completeStream.ToArray();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (completeStream != null)
                    completeStream.Dispose();
                if (g != null)
                    g.Dispose();
                if (backbitmap != null)
                    backbitmap.Dispose();
                if (backimage != null)
                    backimage.Dispose();
                if (qrimage != null)
                    qrimage.Dispose();
                if (backStream != null)
                    backStream.Dispose();
                if (qrStream != null)
                    qrStream.Dispose();
            }

            return img;


        }

        /// <summary>
        /// 转换为  QueryString 格式 如：param1=value1&param2=value2
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static string DictionaryToQueryString(this NameValueCollection values)
        {
            StringBuilder url = new StringBuilder();
            foreach (string item in values.Keys)
            {
                url.AppendFormat("{0}={1}&", item, HttpUtility.UrlEncode(values[item]));
            }
            return url.ToString().TrimEnd('&');

        }


        #region 获取快递信息
        ///// <summary>
        ///// 使用任务对象获取快递信息
        ///// </summary>
        ///// <param name="billcode">运单号</param>
        ///// <param name="waybillCompany">快递公司</param>
        ///// <returns></returns>
        //public static async Task<KuaiDiQueryData> GetKuaiDiQueryDataTaskAsync(string billcode, WaybillCompanyEnum waybillCompany)
        //{
        //    if (!string.IsNullOrWhiteSpace(billcode) && DefaultInstance.Instance.KuaiDiQueryManage != null && DefaultInstance.Instance.KuaiDiQueryManage.ContainsKey(waybillCompany))
        //    {
        //        return await DefaultInstance.Instance.KuaiDiQueryManage[waybillCompany].GetAsync(billcode);
        //    }
        //    return null;
        //}

        ///// <summary>
        ///// 获取快递信息
        ///// </summary>
        ///// <param name="billcode">运单号</param>
        ///// <param name="waybillCompany">快递公司</param>
        ///// <returns></returns>
        //public static KuaiDiQueryData GetKuaiDiQueryData(string billcode, WaybillCompanyEnum waybillCompany)
        //{
        //    if (!string.IsNullOrWhiteSpace(billcode) && DefaultInstance.Instance.KuaiDiQueryManage != null && DefaultInstance.Instance.KuaiDiQueryManage.ContainsKey(waybillCompany))
        //    {
        //        try
        //        {
        //            return DefaultInstance.Instance.KuaiDiQueryManage[waybillCompany].Get(billcode);
        //        }
        //        catch (KuaiDiQueryFailException ex)
        //        {
        //            DefaultInstance.Instance.AliPayLoggerHelper.Warn("物流查询失败", ex);
        //        }
        //        catch (Exception ex)
        //        {
        //            DefaultInstance.Instance.AliPayLoggerHelper.Warn("物流查询出错", ex);
        //        }
        //    }
        //    return null;
        //}

        ///// <summary>
        ///// 获取任务对象快递信息
        ///// </summary>
        ///// <typeparam name="KuaiDiQueryData"></typeparam>
        ///// <param name="task">任务</param>
        ///// <returns></returns>
        //public static KuaiDiQueryData GetKuaiDiQueryDataTaskResult(this Task<KuaiDiQueryData> task)
        //{
        //    try
        //    {
        //        return task.ConfigureAwait(false).GetAwaiter().GetResult();
        //    }
        //    catch (AggregateException ex)
        //    {
        //        var queryex = ex.GetBaseException();
        //        if (queryex is KuaiDiQueryFailException)
        //        {
        //            DefaultInstance.Instance.AliPayLoggerHelper.Warn("物流查询失败", queryex);
        //        }
        //        else
        //            DefaultInstance.Instance.AliPayLoggerHelper.Warn("物流查询出错", ex);
        //    }
        //    catch (Exception ex)
        //    {
        //        DefaultInstance.Instance.AliPayLoggerHelper.Warn("物流查询出错", ex);
        //    }
        //    return default(KuaiDiQueryData);
        //}
        #endregion

        /// <summary>
        /// 从Config文件夹中获取配置文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static T GetXMLConfigFile<T>(string filename)
        {
            if (string.IsNullOrWhiteSpace(filename)) filename = nameof(T);
            var filepath = System.IO.Path.Combine(System.Environment.CurrentDirectory, $@"Config\{filename}.Config");
            string xml = null;
            if (!System.IO.File.Exists(filepath))
            {
                throw new Exception($"配置文件未找到 {filepath}");
            }
            try
            {
                xml = System.IO.File.ReadAllText(filepath);
                return TEC.Public.Common.XmlSerializationHelper.DeSerialize<T>(xml);
            }
            catch (Exception ex)
            {
                throw new Exception($"Android推送配置文件格式不正确 {xml}", ex);
            }
        }

        public static bool IsNullOrEmpty(this Guid value)
        {
            return value == Guid.Empty || value == null;
        }
        public static bool IsNullOrEmpty(this Guid? value)
        {
            return !value.HasValue || value == Guid.Empty || value == null;
        }

        private static int _OrderNum = new Random().Next();
        public static string CreateOrderNum()
        {
            var num = Interlocked.Increment(ref _OrderNum) % 10000;//只要后4位
            return $"{num.ToString("0000")}{DateTime.Now.Millisecond.ToString("000")}";
        }
    }
}



